package com.music.note_android.ui.editor

import android.graphics.Color
import android.graphics.PointF
import android.os.SystemClock
import android.util.Log
import kotlinx.coroutines.*
import kotlin.math.cos
import kotlin.math.sin
import kotlin.random.Random

/**
 * 画布测试工具类
 * 用于自动化测试画布功能和性能验证
 */
class CanvasTester {
    
    companion object {
        private const val TAG = "CanvasTester"
        private const val TEST_DURATION = 10000L // 测试持续时间10秒
        private const val STRESS_TEST_STROKES = 1000 // 压力测试笔画数量
    }
    
    private val performanceMonitor = PerformanceMonitor()
    private var testJob: Job? = null
    
    /**
     * 测试结果回调
     */
    interface TestCallback {
        fun onTestStarted(testName: String)
        fun onTestProgress(progress: Int, message: String)
        fun onTestCompleted(testName: String, result: TestResult)
        fun onTestFailed(testName: String, error: String)
    }
    
    /**
     * 运行基础功能测试
     */
    fun runBasicFunctionalityTest(
        canvasView: DrawingCanvasView,
        callback: TestCallback
    ) {
        testJob = CoroutineScope(Dispatchers.Main).launch {
            try {
                callback.onTestStarted("基础功能测试")
                
                val results = mutableListOf<String>()
                
                // 测试1: 绘制功能
                callback.onTestProgress(10, "测试绘制功能...")
                val drawResult = testDrawingFunctionality(canvasView)
                results.add("绘制功能: ${if (drawResult) "通过" else "失败"}")
                
                // 测试2: 工具切换
                callback.onTestProgress(30, "测试工具切换...")
                val toolResult = testToolSwitching(canvasView)
                results.add("工具切换: ${if (toolResult) "通过" else "失败"}")
                
                // 测试3: 撤销重做
                callback.onTestProgress(50, "测试撤销重做...")
                val undoRedoResult = testUndoRedo(canvasView)
                results.add("撤销重做: ${if (undoRedoResult) "通过" else "失败"}")
                
                // 测试4: 缩放拖拽
                callback.onTestProgress(70, "测试缩放拖拽...")
                val gestureResult = testGestures(canvasView)
                results.add("缩放拖拽: ${if (gestureResult) "通过" else "失败"}")
                
                // 测试5: 橡皮擦功能
                callback.onTestProgress(90, "测试橡皮擦功能...")
                val eraserResult = testEraserFunctionality(canvasView)
                results.add("橡皮擦功能: ${if (eraserResult) "通过" else "失败"}")
                
                callback.onTestProgress(100, "测试完成")
                
                val overallResult = results.all { it.contains("通过") }
                callback.onTestCompleted(
                    "基础功能测试",
                    TestResult(
                        passed = overallResult,
                        details = results,
                        duration = 0L
                    )
                )
                
            } catch (e: Exception) {
                callback.onTestFailed("基础功能测试", e.message ?: "未知错误")
            }
        }
    }
    
    /**
     * 运行性能压力测试
     */
    fun runPerformanceStressTest(
        canvasView: DrawingCanvasView,
        callback: TestCallback
    ) {
        testJob = CoroutineScope(Dispatchers.Main).launch {
            try {
                callback.onTestStarted("性能压力测试")
                
                performanceMonitor.reset()
                val startTime = SystemClock.elapsedRealtime()
                
                // 生成大量笔画进行压力测试
                for (i in 0 until STRESS_TEST_STROKES) {
                    val progress = (i * 100) / STRESS_TEST_STROKES
                    callback.onTestProgress(progress, "生成笔画 $i/$STRESS_TEST_STROKES")
                    
                    // 模拟绘制复杂笔画
                    simulateComplexStroke(canvasView)
                    
                    // 每100笔画检查一次性能
                    if (i % 100 == 0) {
                        performanceMonitor.updateMemoryUsage()
                        delay(10) // 给UI线程一些时间
                    }
                }
                
                val endTime = SystemClock.elapsedRealtime()
                val duration = endTime - startTime
                
                val performanceReport = performanceMonitor.getPerformanceReport()
                
                val results = listOf(
                    "测试时长: ${duration}ms",
                    "平均FPS: ${performanceReport.averageFPS}",
                    "最低FPS: ${performanceReport.minFPS}",
                    "平均绘制时间: ${performanceReport.averageDrawTime}ms",
                    "内存使用: ${performanceReport.memoryInfo.current / 1024 / 1024}MB",
                    "峰值内存: ${performanceReport.memoryInfo.peak / 1024 / 1024}MB"
                )
                
                val passed = performanceReport.averageFPS >= 30 && 
                           performanceReport.averageDrawTime < 50
                
                callback.onTestCompleted(
                    "性能压力测试",
                    TestResult(
                        passed = passed,
                        details = results,
                        duration = duration
                    )
                )
                
            } catch (e: Exception) {
                callback.onTestFailed("性能压力测试", e.message ?: "未知错误")
            }
        }
    }
    
    /**
     * 运行内存泄漏测试
     */
    fun runMemoryLeakTest(
        canvasView: DrawingCanvasView,
        callback: TestCallback
    ) {
        testJob = CoroutineScope(Dispatchers.Main).launch {
            try {
                callback.onTestStarted("内存泄漏测试")
                
                val runtime = Runtime.getRuntime()
                val initialMemory = runtime.totalMemory() - runtime.freeMemory()
                
                // 执行多轮绘制和清理操作
                for (round in 1..10) {
                    callback.onTestProgress(round * 10, "执行第 $round 轮测试...")
                    
                    // 绘制大量笔画
                    repeat(100) {
                        simulateRandomStroke(canvasView)
                    }
                    
                    // 清空画布
                    canvasView.clearCanvas()
                    
                    // 强制垃圾回收
                    System.gc()
                    delay(100)
                }
                
                val finalMemory = runtime.totalMemory() - runtime.freeMemory()
                val memoryIncrease = finalMemory - initialMemory
                val memoryIncreasePercent = (memoryIncrease.toFloat() / initialMemory) * 100
                
                val results = listOf(
                    "初始内存: ${initialMemory / 1024 / 1024}MB",
                    "最终内存: ${finalMemory / 1024 / 1024}MB",
                    "内存增长: ${memoryIncrease / 1024 / 1024}MB",
                    "增长百分比: ${memoryIncreasePercent.toInt()}%"
                )
                
                val passed = memoryIncreasePercent < 20 // 内存增长不超过20%
                
                callback.onTestCompleted(
                    "内存泄漏测试",
                    TestResult(
                        passed = passed,
                        details = results,
                        duration = 0L
                    )
                )
                
            } catch (e: Exception) {
                callback.onTestFailed("内存泄漏测试", e.message ?: "未知错误")
            }
        }
    }
    
    /**
     * 测试绘制功能
     */
    private suspend fun testDrawingFunctionality(canvasView: DrawingCanvasView): Boolean {
        return try {
            // 切换到钢笔工具
            canvasView.setCurrentTool(DrawingTool.PEN)
            canvasView.setCurrentColor(Color.BLACK)
            canvasView.setStrokeWidth(5f)
            
            // 模拟绘制一条线
            simulateDrawLine(canvasView, 100f, 100f, 200f, 200f)
            
            delay(100)
            true
        } catch (e: Exception) {
            Log.e(TAG, "绘制功能测试失败", e)
            false
        }
    }
    
    /**
     * 测试工具切换
     */
    private suspend fun testToolSwitching(canvasView: DrawingCanvasView): Boolean {
        return try {
            val tools = listOf(
                DrawingTool.PEN,
                DrawingTool.PENCIL,
                DrawingTool.HIGHLIGHTER,
                DrawingTool.ERASER
            )
            
            tools.forEach { tool ->
                canvasView.setCurrentTool(tool)
                delay(50)
            }
            
            true
        } catch (e: Exception) {
            Log.e(TAG, "工具切换测试失败", e)
            false
        }
    }
    
    /**
     * 测试撤销重做功能
     */
    private suspend fun testUndoRedo(canvasView: DrawingCanvasView): Boolean {
        return try {
            // 绘制几条线
            repeat(3) {
                simulateRandomStroke(canvasView)
                delay(50)
            }
            
            // 测试撤销
            canvasView.undo()
            delay(50)
            
            // 测试重做
            canvasView.redo()
            delay(50)
            
            true
        } catch (e: Exception) {
            Log.e(TAG, "撤销重做测试失败", e)
            false
        }
    }
    
    /**
     * 测试手势功能
     */
    private suspend fun testGestures(canvasView: DrawingCanvasView): Boolean {
        return try {
            // 这里应该模拟缩放和拖拽手势
            // 由于手势模拟比较复杂，这里简化处理
            delay(100)
            true
        } catch (e: Exception) {
            Log.e(TAG, "手势测试失败", e)
            false
        }
    }
    
    /**
     * 测试橡皮擦功能
     */
    private suspend fun testEraserFunctionality(canvasView: DrawingCanvasView): Boolean {
        return try {
            // 先绘制一些内容
            simulateRandomStroke(canvasView)
            delay(50)
            
            // 切换到橡皮擦
            canvasView.setCurrentTool(DrawingTool.ERASER)
            
            // 模拟擦除操作
            simulateRandomStroke(canvasView)
            delay(50)
            
            true
        } catch (e: Exception) {
            Log.e(TAG, "橡皮擦测试失败", e)
            false
        }
    }
    
    /**
     * 模拟绘制直线
     */
    private fun simulateDrawLine(
        canvasView: DrawingCanvasView,
        startX: Float, startY: Float,
        endX: Float, endY: Float
    ) {
        // 这里应该模拟触摸事件来绘制直线
        // 由于需要访问私有方法，这里简化处理
    }
    
    /**
     * 模拟绘制随机笔画
     */
    private fun simulateRandomStroke(canvasView: DrawingCanvasView) {
        // 生成随机笔画数据
        val startX = Random.nextFloat() * 500 + 100
        val startY = Random.nextFloat() * 500 + 100
        val endX = startX + Random.nextFloat() * 200 - 100
        val endY = startY + Random.nextFloat() * 200 - 100
        
        simulateDrawLine(canvasView, startX, startY, endX, endY)
    }
    
    /**
     * 模拟绘制复杂笔画
     */
    private fun simulateComplexStroke(canvasView: DrawingCanvasView) {
        // 生成螺旋形笔画
        val centerX = 300f
        val centerY = 300f
        val points = mutableListOf<PointF>()
        
        for (i in 0..50) {
            val angle = i * 0.2f
            val radius = i * 2f
            val x = centerX + cos(angle) * radius
            val y = centerY + sin(angle) * radius
            points.add(PointF(x, y))
        }
        
        // 这里应该将点列表转换为实际的绘制操作
    }
    
    /**
     * 停止当前测试
     */
    fun stopTest() {
        testJob?.cancel()
        testJob = null
    }
    
    /**
     * 测试结果数据类
     */
    data class TestResult(
        val passed: Boolean,
        val details: List<String>,
        val duration: Long
    )
}